package client.ftp;

import java.util.HashMap;
import util.pref.PrefHandler;

/**
 * This is the Implementation of the FTPInterface.
 * It has three methods, one for uploading, one for downloading and one that
 * loads the preferences.
 * @author Robert
 */
public class FTPImplementation implements FTPInterface {

    /**
     * Whether or not settings are loaded
     */
    private Boolean loaded = false;
    /**
     * the host name of the ftp server
     */
    private String hostname;
    /**
     * the user name of the ftp account
     */
    private String username;
    /**
     * the password of the ftp account
     */
    private String password;
    /**
     * the path of the local folder where the project files are stored
     */
    private String localFolder;
    /**
     * the path of the remote folder where the project files are stored
     */
    private String remoteFolder;
    /**
     * the connection type, possible options: FTPS, SFTP or FTP(default)    
     */
    private String connectionType;
    /**
     * the port number to connect to
     */
    private int port;
    /**
     * for sftp: the path to the privat key file
     */
    private String privateKeyPath;
    /**
     * for sftp: whether or whether or not to use a privat key
     */
    private Boolean usePrivateKey;
    /**
     * FTP(S) transfer object
     */
    private FTPHandler fth;
    /**
     * SFTP transfer object
     */
    private SFTPHandler sfth;

    /**
     * Uploads a file to a server
     * @param localfilepath The local path of the file to upload
     * @return True if uploaded successfully, false otherwise
     */
    public Boolean upload(String localFile) {
        Boolean uploaded = false;
        if (loaded == true) {
            /**
             * Determines the connection type
             */
            if (connectionType.equals("FTPS")) {
                fth = new FTPSHandler(hostname, username, password, port);
            } else if (connectionType.equals("SFTP")) {
                sfth = new SFTPHandler(hostname, username, password, port, privateKeyPath, usePrivateKey);
            } else {
                fth = new FTPHandler(hostname, username, password, port);
            }

            /**
             * Checks first if FTP, FTPS or SFTP. Checks first if connected, 
             * then if logged in, then if successfully uploaded. Returns true 
             * if all of them are successful.
             */
            if (connectionType.equals("FTP") || connectionType.equals("FTPS")) {
                if (fth.connect() == 0) {
                    if (fth.login() == 0) {
                        if (fth.upload(localFile, remoteFolder) == 0) {
                            uploaded = true;
                        }
                    }
                    fth.disconnect();
                }
            } else if (connectionType.equals("SFTP")) {
                if (sfth.upload(localFile, remoteFolder) == 0) {
                    uploaded = true;
                }
            } else {
                System.out.println("No connection type selected. Must be FTP, FTPS or SFTP.");
            }
        }
        return uploaded;
    }

    /**
     * Downloads a file from a server
     * @param remotefilepath The remote path of the file to download
     * @return True if downloaded successfully, false otherwise
     */
    public Boolean download(String remoteFile) {
        Boolean downloaded = false;
        if (loaded == true) {
            /**
             * Determines the connection type
             */
            if (connectionType.equals("FTPS")) {
                fth = new FTPSHandler(hostname, username, password, port);
            } else if (connectionType.equals("SFTP")) {
                sfth = new SFTPHandler(hostname, username, password, port, privateKeyPath, usePrivateKey);
            } else {
                fth = new FTPHandler(hostname, username, password, port);
            }

            /**
             * checks first if connected, then if logged in, then if successfully 
             * downloaded. Returns true if all of them are successful
             */
            if (connectionType.equals("FTP") || connectionType.equals("FTPS")) {
                if (fth.connect() == 0) {//if successfully connected
                    if (fth.login() == 0) {//if successfully logged in
                        if (fth.download(remoteFile, localFolder) == 0) {
                            //if successfully downloaded
                            downloaded = true;
                        }
                        }
                    fth.disconnect();//close the connection
                }
            } else if (connectionType.equals("SFTP")) {
                if (sfth.download(remoteFile, remoteFolder, localFolder) == 0) {
                    downloaded = true;
                }
            } else {
                System.out.println("No connection type selected. Must be FTP, FTPS or SFTP.");
            }
        }
        return downloaded;
    }

    /**
     * loads all ftp related settings like ftp details and connection 
     * preferences, by utilizing the PrefHandler class
     */
    public void loadSettings() {
        System.out.println("Loading file transfer settings...");
        /**
         * creating the string array to hold all the keys
         */
        String[] s = new String[9];
        s[0] = "HOSTNAME";
        s[1] = "USERNAME";
        s[2] = "PASSWORD";
        s[3] = "LOCALFOLDER";
        s[4] = "REMOTEFOLDER";
        s[5] = "CONNECTIONTYPE";
        s[6] = "PORT";
        s[7] = "PRIVATEKEYPATH";
        s[8] = "USEPRIVATEKEY";
        /**
         * creating a new preferences object and calling getPreferences method, 
         * and storing the result in a HashMap
         */
        PrefHandler p = new PrefHandler();
        HashMap<String,String> h = p.getPreferences(s);
        
        /**
         * getting all values from the HashMap and storing them in the class
         * variables
         */
        this.hostname = h.get("HOSTNAME").toString();
        this.username = h.get("USERNAME").toString();
        this.password = h.get("PASSWORD").toString();
        this.localFolder = h.get("LOCALFOLDER").toString();
        this.remoteFolder = h.get("REMOTEFOLDER").toString();
        this.connectionType = h.get("CONNECTIONTYPE").toString();
        this.port = Integer.parseInt(h.get("PORT").toString());
        this.privateKeyPath = h.get("PRIVATEKEYPATH").toString();
        this.usePrivateKey = Boolean.parseBoolean(h.get("USEPRIVATEKEY").toString());
        System.out.println("Done.");
        loaded = true;
    }
}
